#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/un.h>

#define PARAMETROS 3

#define SOCKET_FILE "/tmp/socket_file"


int  Gfd, Gclient_fd;


//===========================================================
void Abortar (const char *msg) {
   fprintf (stderr, "Simulador: %s\n", msg);
   exit   (-1);
}

//===========================================================
bool ConectarNomad () {

    struct sockaddr_un addr;
    Gfd = socket(AF_UNIX, SOCK_STREAM, 0);
    Gclient_fd;

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strcpy(addr.sun_path, SOCKET_FILE);
    unlink(addr.sun_path);


//struct timeval tv;
//tv.tv_sec  = 7;
//tv.tv_usec = 0;
//setsockopt(Gfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);


    if (bind(Gfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
      printf("bind failed\n");
      return false;
    }

    if (listen(Gfd, 1) == -1) {
      printf("listen failed\n");
      return false;
    }

//    fprintf(stderr, "Esperando conexão...\n");

    Gclient_fd = accept(Gfd, NULL, NULL);

    if (Gclient_fd == -1) {
      fprintf(stderr, "Conexão Falhou.\n");
      return false;
    }

    //fprintf(stderr, "Conexão Aceita!\n");

    return true;
}

//===========================================================
void ReceberNomad (double *parametros) {

   for (int i = 0; i < PARAMETROS; i++)
      while (0 >= read (Gclient_fd, &parametros[i], sizeof (double))) 
         ;
 //        Abortar ("Problema ao receber parâmetros.\n");

//   fprintf (stderr, "Simulador recebeu parâmetros ");
//   for (int i = 0; i < PARAMETROS; i++)
//      fprintf (stderr, "%f ", parametros[i]);

//   fprintf (stderr, "\n");

}


//===========================================================
void EnviarNomad (double valor) {

//   fprintf (stderr, "Simulador envia rede... \n");

   if (0 >= write (Gclient_fd, &valor, sizeof (double))) 
      Abortar ("Problema ao receber parâmetros.\n");

//   fprintf (stderr, " [%f] \n", valor);

}


//===========================================================
void Finalizar () {
   close  (Gfd);
}




//===========================================================
//     SIMULADOR
//===========================================================


int mainteste () {


   for (int i = 0; i < 100; i++) {

      ConectarNomad ();

      double parametros[PARAMETROS];

      fprintf (stderr, "Simulador lê.\n");

      ReceberNomad (parametros);

      double x = parametros[0];
      double y = parametros[1];

      x = x - 1.234;
      y = y + 4.321;

      double valor = 2 * x * x + 1.5 * y * y;

      fprintf (stderr, "Simulador escreve.\n");

      EnviarNomad (valor);
   }

   Finalizar ();

   return 0;
} 

